package com.teckteam.ptvsystem.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import com.teckteam.ptvsystem.controller.CancelWindowListener;
import com.teckteam.ptvsystem.controller.CreateJourneyPlanListener;
import com.teckteam.ptvsystem.model.AbstractStop;
import com.teckteam.ptvsystem.model.facade.PTVConstants;
import com.teckteam.ptvsystem.model.facade.PTVModel;
import com.teckteam.ptvsystem.model.facade.PTVSystem;

/**
 * Dialog box for Journey Planner ; all GUI elements are placed here to be
 * passed into the PTVModel interface for retrieving Journey plan results.
 */
public class JourneyPlanner extends JDialog
{
   private JLabel 
      time = new JLabel("Departure Time:");
   
   private JPanel 
      planPanel = new JPanel(new GridLayout(2, 1)),
      btnPanel = new JPanel(new GridLayout(2, 1)), screen = new JPanel(),
      timePanel = new JPanel();
   
   private JourneyChoicePanel
      sourcePanel, destPanel;
   
   private JButton
      planBtn = new JButton("Plan new Journey"),
      filterBtn = new JButton("Plan options"),
      cancelBtn = new JButton("Cancel");
   
   private JComboBox
      ampmMode = new JComboBox(),
      minsBox = new JComboBox(), hrsBox = new JComboBox(),
      dayBox = new JComboBox();
   
   private ArrayList<AbstractStop> stopList;
   private ArrayList<String> suburbList;
   
   private String dTime, origin, destination;
   
   /**
    * Constructor to initialize Journey Planner dialog box
    * @param suburbList
    * @param stopList
    */
   public JourneyPlanner(ArrayList<String> suburbList,
         ArrayList<AbstractStop> stopList)
   {
      this.stopList = stopList;
      this.suburbList = suburbList;
      ArrayList<String> stopStrings = new ArrayList<String>();
      
      this.setSize(new Dimension(500, 300));
      this.setLocationRelativeTo(PTVUserInterface.getInstance());
      this.setLayout(new BorderLayout());
      this.setResizable(false);
      this.setTitle("Journey Planner:");
      this.setModal(true);
      
      ampmMode.addItem("am");
      ampmMode.addItem("pm");
      
      int hrsVals[] = new int[12], minVals[] = new int[60];
      
      //Populate hours
      for (int i = 1; i <= hrsVals.length; i++)
      {
         hrsVals[i-1] = i;
         hrsBox.addItem(Integer.toString(hrsVals[i-1]));
      }
      
      //Populate minutes
      for (int i = 0; i < minVals.length; i++)
      {
         minVals[i] = i;
         minsBox.addItem(String.format("%02d", minVals[i]));
      }
      
      for (int i = 0; i < PTVConstants.daysOfWeek.length; i++)
         dayBox.addItem(PTVConstants.daysOfWeek[i]);
      
      
      // Anonymous inner class actions
      planBtn.addActionListener(
            new CreateJourneyPlanListener(this));
      
      cancelBtn.addActionListener(new CancelWindowListener(this));
      
      planPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
      planPanel.setPreferredSize(new Dimension(480, 170));
      
      //Sort stop strings
      Set filterSet = new HashSet();
      for(AbstractStop s : stopList)
         if(filterSet.add(s.toString()))
            stopStrings.add(s.toString());
      
      Collections.sort(stopStrings);
      sourcePanel = new JourneyChoicePanel(this, stopStrings, "From:");
      destPanel = new JourneyChoicePanel(this, stopStrings, "To:");
      
      timePanel.add(time);
      timePanel.add(hrsBox);
      timePanel.add(minsBox);
      timePanel.add(ampmMode);
      timePanel.add(dayBox);
      
      btnPanel.add(planBtn);
      btnPanel.add(filterBtn);
      btnPanel.add(cancelBtn);
      
      filterBtn.addActionListener(new ActionListener() 
      {
         public void actionPerformed(ActionEvent e)
         {
            JOptionPane.showMessageDialog(JourneyPlanner.this, "Functionality Disabled");
         }
      });
      
      planPanel.add(sourcePanel, 0);
      planPanel.add(destPanel, 1);
      
      screen.add(timePanel);
      screen.add(planPanel);
      screen.add(btnPanel, BorderLayout.SOUTH);
      
      setCurrentTime();
      
      this.getContentPane().add(screen);
      this.setVisible(true);
   }
   
   /**
    * Accessor for retrieving form values to be processed
    * 
    * @return vals
    */
   public String[] getFormValues()
   {
      String[] vals = new String[3];
      
      vals[0] = String.format(
            "%s:%s-%s", hrsBox.getSelectedItem().toString(),
            minsBox.getSelectedItem().toString(), 
            ampmMode.getSelectedItem().toString()
      );
      
      vals[1] = sourcePanel.getSelected();
      vals[2] = destPanel.getSelected();
      
      return vals;
   }
   
   /**
    * Sets timePanel elements to have current time of day by default.
    */
   private void setCurrentTime()
   {
      Calendar calendar = Calendar.getInstance();
      if(calendar.get(Calendar.HOUR)==0)
         hrsBox.setSelectedIndex(11);
      else
         hrsBox.setSelectedIndex(calendar.get(Calendar.HOUR)-1);
      
      minsBox.setSelectedIndex(calendar.get(Calendar.MINUTE));
      ampmMode.setSelectedIndex(calendar.get(Calendar.AM_PM));
      dayBox.setSelectedIndex(calendar.get(Calendar.DAY_OF_WEEK)-1);
   }
   
   /**
    * Get stop list (unused)
    * 
    * @return
    */
   protected ArrayList<AbstractStop> getStopList()
   {
      return stopList;
   }
   
   /**
    * Suburb list getter
    * 
    * @return
    */
   protected ArrayList<String> getSuburbList()
   {
      return suburbList;
   }
   
   /**
    * Show error message. Used for failed validation.
    * 
    * @param message
    */
   public void setError(String message)
   {
      JOptionPane.showMessageDialog(this,
            message, "Form validation failed", JOptionPane.ERROR_MESSAGE);
   }
   
}